package com.mhc.suzuki.service.impl;

import com.alibaba.fastjson.JSON;
import com.mhc.haval.api.dto.StaffDTO;
import com.mhc.haval.api.service.IStaffRoleService;
import com.mhc.haval.security.service.IStaffService;
import com.mhc.suzuki.bo.*;
import com.mhc.suzuki.constant.*;
import com.mhc.suzuki.dal.model.*;
import com.mhc.suzuki.dal.query.*;
import com.mhc.suzuki.exception.SuzukiCommonException;
import com.mhc.suzuki.manager.*;
import com.mhc.suzuki.service.OverdueService;
import com.mhc.suzuki.util.BeanCopierUtil;
import com.mhc.suzuki.vo.DepartmentVO;
import com.mhc.suzuki.vo.OrderVO;
import com.mhc.suzuki.vo.OverdueCollectTaskVO;
import com.mhc.suzuki.vo.OverdueListVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author Churry
 * @create 2017-08-25 16:59
 **/
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class OverdueServiceImpl implements OverdueService {

    @Autowired
    OrderManager orderManager;
    @Autowired
    PostBankCardManager postBankCardManager;
    @Autowired
    LoanInfoManager loanInfoManager;
    @Autowired
    DataDictManager dataDictManager;
    @Autowired
    OverdueListManager overdueListManager;
    @Autowired
    DebtCollectHisManager debtCollectHisManager;
    @Autowired
    TowingHisManager towingHisManager;
    @Autowired
    LawsuitHisManager lawsuitHisManager;
    @Autowired
    CarInfoManager carInfoManager;
    @Autowired
    OverdueCollectTaskManager overdueCollectTaskManager;
    @Autowired
    IStaffService iStaffService;
    @Autowired
    IStaffRoleService staffRoleService;

    /**
     * 查询逾期清单列表，查询条件可以有客户姓名，客户身份证号，银行名称
     *
     * @param overdueListQuery
     * @return
     */
    @Override
    public List<OverdueListVO> getOverdueList(OverdueListQuery overdueListQuery) throws SuzukiCommonException {
        try {
            List<OverdueListVO> overdueListVOList = new ArrayList<>();
            for (OverdueListDO overdueListDO : overdueListManager.selectByQuery(overdueListQuery)) {
                OverdueListVO overdueListVO = BeanCopierUtil.convert(overdueListDO, OverdueListVO.class);
                String repayDate = overdueListVO.getRepaymentDate();
                overdueListVO.setRepaymentDate(repayDate.substring(repayDate.length() - 2));
                overdueListVOList.add(overdueListVO);
            }
            return overdueListVOList;
        } catch (Exception e) {
            log.error("Exception", e);
            throw new SuzukiCommonException(ErrorCodeEnum.QUERY_OVERDUE_LIST_FAIL);
        }
    }

    /**
     * 查询只根据逾期记录中的银行卡号，能查到的所有订单号
     *
     * @param overdueId
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public List<String> getOrderNoByOverdueId(Long overdueId) throws SuzukiCommonException {
        Optional<Long> overdueIdOptional = Optional.ofNullable(overdueId);
        if (overdueIdOptional.isPresent()) {
            List<String> orderNoList = new ArrayList<>();
            OverdueListDO overdueListDO = overdueListManager.selectByPrimaryKey(overdueId);
            //根据银行卡号找到所有订单编号
            PostBankCardQuery postBankCardQuery = new PostBankCardQuery();
            postBankCardQuery.createCriteria().andRepayAccountEqualTo(overdueListDO.getBankCardNo());
            for (PostBankCardDO postBankCardDO : postBankCardManager.selectByQuery(postBankCardQuery)) {
                orderNoList.add(postBankCardDO.getOrderNo());
            }
            return orderNoList;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.OVERDUE_ID_ISNULL);
        }
    }

    /**
     * 查询逾期列表总数目
     *
     * @param overdueListQuery
     * @return
     */
    @Override
    public Integer getCountByQuery(OverdueListQuery overdueListQuery) {
        return overdueListManager.countByQuery(overdueListQuery);
    }

    /**
     * 根据逾期记录编号与已确定的订单编号，获取催收记录详情
     *
     * @param orderNo
     * @return
     */
    @Override
    public DebtCollectDetailBO getDebtCollectDetail(String orderNo) throws SuzukiCommonException {
        Optional<String> orderNoOptional = Optional.ofNullable(orderNo);
        if (orderNoOptional.isPresent()) {
            DebtCollectDetailBO debtCollectDetailBO = new DebtCollectDetailBO();
            debtCollectDetailBO.setOrderNo(orderNo);
            debtCollectDetailBO.setAssetsAnnexGroup(AnnexGroupEnum.ASSETS.getCode());
            try {
                //获取订单详情
                OrderDO orderDO = orderManager.selectByOrderNo(orderNo);
                debtCollectDetailBO.setAnnexBatchNo(orderDO.getAnnexBatchNo());
                //根据订单编号查找催收记录（包含电催和上门催收）
                List<DebtCollectHisBO> callingDebtList = new ArrayList<>();
                List<DebtCollectHisBO> visitDebtList = new ArrayList<>();
                DebtCollectHisQuery debtCollectHisQuery = new DebtCollectHisQuery();
                debtCollectHisQuery.createCriteria().andOrderNoEqualTo(orderNo);
                //分别放入电催和上门催收列表
                for (DebtCollectHisDO debtCollectHisDO : debtCollectHisManager.selectByQuery(debtCollectHisQuery)) {
                    DebtCollectHisBO debtCollectHisBO = BeanCopierUtil.convert(debtCollectHisDO, DebtCollectHisBO.class);
                    //获取催收执行人姓名
                    debtCollectHisBO.setCollectorStaffName(iStaffService.getUserByStaffId(debtCollectHisBO.getCollectorStaffId()).getStaffName());
                    //0代表电催，1代表上门
                    switch (debtCollectHisBO.getCollectType()) {
                        //放入对应的列表
                        case 0:
                            callingDebtList.add(debtCollectHisBO);
                            break;
                        case 1:
                            visitDebtList.add(debtCollectHisBO);
                            break;
                        default:
                    }
                }
                debtCollectDetailBO.setCallingDebtList(callingDebtList);
                debtCollectDetailBO.setVisitDebtList(visitDebtList);
            } catch (Exception e) {
                log.error("查找催收记录失败,orderNo="+orderNo, e);
                throw new SuzukiCommonException(ErrorCodeEnum.QUERY_DEBT_COLLECT_DETAIL_FAIL);
            }
            try {
                //查找拖车记录
                List<TowingHisBO> towingHisBOList = new ArrayList<>();
                TowingHisQuery towingHisQuery = new TowingHisQuery();
                towingHisQuery.createCriteria().andOrderNoEqualTo(orderNo);
                for (TowingHisDO towingHisDO : towingHisManager.selectByQuery(towingHisQuery)) {
                    TowingHisBO towingHisBO = BeanCopierUtil.convert(towingHisDO, TowingHisBO.class);
                    //获取拖车执行人姓名
                    towingHisBO.setExecStaffName(iStaffService.getUserByStaffId(towingHisBO.getExecStaffId()).getStaffName());
                    towingHisBOList.add(towingHisBO);
                }
                debtCollectDetailBO.setTowingHisList(towingHisBOList);
            } catch (Exception e) {
                log.error("查找拖车记录失败,orderNo="+orderNo, e);
                throw new SuzukiCommonException(ErrorCodeEnum.QUERY_TOWING_HIS_LIST_FAIL);
            }
            try {
                //查找法院诉讼记录
                List<LawsuitHisBO> lawsuitHisBOList = new ArrayList<>();
                LawsuitHisQuery lawsuitHisQuery = new LawsuitHisQuery();
                lawsuitHisQuery.createCriteria().andOrderNoEqualTo(orderNo);
                for (LawsuitHisDO lawsuitHisDO : lawsuitHisManager.selectByQuery(lawsuitHisQuery)) {
                    LawsuitHisBO lawsuitHisBO = BeanCopierUtil.convert(lawsuitHisDO, LawsuitHisBO.class);
                    lawsuitHisBOList.add(lawsuitHisBO);
                }
                debtCollectDetailBO.setLawsuitHisList(lawsuitHisBOList);
            } catch (Exception e) {
                log.error("查找法院诉讼记录失败,orderNo="+orderNo, e);
                throw new SuzukiCommonException(ErrorCodeEnum.QUERY_LAWSUIT_HIS_LIST_FAIL);
            }
            return debtCollectDetailBO;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.ORDER_NO_ISNULL);
        }
    }

    /**
     * 根据查询条件（多条订单编号），获取对应的订单列表
     *
     * @param orderQuery
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public List<OrderVO> getOverdueOrderList(OrderQuery orderQuery) throws SuzukiCommonException {
        try {
            List<OrderVO> orderVOList = new ArrayList<>();
            List<OrderDO> orderDOList = orderManager.selectByQuery(orderQuery);
            if(CollectionUtils.isNotEmpty(orderDOList)){
                orderDOList.forEach(orderDO -> {
                    OrderVO orderVO = BeanCopierUtil.convert(orderDO, OrderVO.class);
                    CarInfoQuery carInfoQuery = new CarInfoQuery();
                    carInfoQuery.createCriteria().andOrderNoEqualTo(orderVO.getOrderNo());
                    List<CarInfoDO> carInfoDOS = carInfoManager.selectByQuery(carInfoQuery);
                    if (carInfoDOS != null && carInfoDOS.size() > 0) {
                        orderVO.setCarModel(carInfoDOS.get(0).getCarModel());
                    }
                    orderVOList.add(orderVO);
                });
            }
            return orderVOList;
        } catch (Exception e) {
            log.error("查询逾期订单列表失败,orderNo="+ JSON.toJSONString(orderQuery), e);
            throw new SuzukiCommonException(ErrorCodeEnum.QUERY_OVERDUE_ORDER_LIST_FAIL);
        }
    }

    /**
     * 获取资产保全部外勤的催收待办列表
     *
     * @param queryMap
     * @return
     */
    @Override
    public List<OverdueCollectTaskVO> getOutWorkerTaskList(Map queryMap) throws SuzukiCommonException {
        Optional<Long> staffIdOptional = Optional.ofNullable(Long.parseLong(queryMap.get("staffId").toString()));
        if (staffIdOptional.isPresent()) {
            List<OverdueCollectTaskVO> overdueCollectTaskVOList = new ArrayList<>();
            for (OverdueCollectTaskVO overdueCollectTaskVO : overdueCollectTaskManager.getOverdueCollectTaskList(queryMap)) {
                //应还款日期截取最后两位，即日期
                String repayDate = overdueCollectTaskVO.getRepaymentDate();
                overdueCollectTaskVO.setRepaymentDate(repayDate.substring(repayDate.length() - 2));
                overdueCollectTaskVOList.add(overdueCollectTaskVO);
            }
            return overdueCollectTaskVOList;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.STAFF_ID_ISNULL);
        }
    }

    /**
     * 上传逾期清单文件
     *
     * @return
     */
    @Override
    public Boolean uploadOverdueList(Long staffId, List<MultipartFile> overdueListFiles) throws SuzukiCommonException {
        List<OverdueListBO> overdueListBOS = new ArrayList<>();
        for (MultipartFile overdueListFile : overdueListFiles) {
            InputStream is = null;
            try {
                is = overdueListFile.getInputStream();
                String fileExtendName = overdueListFile.getOriginalFilename().substring(overdueListFile.getOriginalFilename().lastIndexOf(".") + 1);
                //xls文件使用HSSFWorkbook
                if (FileTypeEnum.XLS.getName().equals(fileExtendName)) {
                    //创建工作薄
                    HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
                    //获取第一张表
                    HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0);
                    //获取数据
                    overdueListBOS.addAll(this.iterateRow(hssfSheet.iterator()));
                }
                //xlsx文件使用XSSFWorkbook
                else if (FileTypeEnum.XLSX.getName().equals(fileExtendName)) {
                    //创建工作薄
                    XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
                    //获取第一张表
                    XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
                    //SXSSF打开方式，但使用iterator时有问题
                    overdueListBOS.addAll(this.iterateRow(xssfSheet.iterator()));
                }
            } catch (Exception e) {
                log.error("Exception", e);
                throw new SuzukiCommonException(ErrorCodeEnum.FILE_UPLOAD_FAIL);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        log.error("IOException", e);
                    }
                }
            }
        }
        //删除旧数据，插入新导入的数据，该方法已设置异常处理，所以在此处不抛出
        //去重,貌似无效
        List<OverdueListBO> duplicateCheck = new ArrayList<>(new LinkedHashSet<>(overdueListBOS));
        this.saveOverdueList(staffId, duplicateCheck);
        return true;
    }

    /**
     * 新增电催记录
     */
    @Override
    public Boolean addCallingDebtRecord(Long staffId, DebtCollectHisBO debtCollectHisBO) throws SuzukiCommonException {
        Optional<DebtCollectHisBO> debtCollectHisBOOptional = Optional.ofNullable(debtCollectHisBO);
        if (debtCollectHisBOOptional.isPresent()) {
            DebtCollectHisDO debtCollectHisDO = BeanCopierUtil.convert(debtCollectHisBO, DebtCollectHisDO.class);
            //增加电催记录的员工和催收人是同一个
            debtCollectHisDO.setStaffId(staffId);
            debtCollectHisDO.setCollectorStaffId(staffId);
            try {
                debtCollectHisManager.insertSelective(debtCollectHisDO);
            } catch (Exception e) {
                log.error(ErrorCodeEnum.INSERT_TEL_DEBT_COLLECT_HIS_FAIL.getErrMsg()+",debtCollectHisBO="+JSON.toJSONString(debtCollectHisBO), e);
                throw new SuzukiCommonException(ErrorCodeEnum.INSERT_TEL_DEBT_COLLECT_HIS_FAIL);
            }
            return true;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.TEL_DEBT_COLLECT_HIS_ISNULL);
        }
    }

    /**
     * 新增上门催收记录
     * @param staffId
     * @param debtCollectHisBO
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean addVisitDebtRecord(Long staffId, DebtCollectHisBO debtCollectHisBO) throws SuzukiCommonException {
        Optional<DebtCollectHisBO> debtCollectHisBOOptional = Optional.ofNullable(debtCollectHisBO);
        if (debtCollectHisBOOptional.isPresent()) {
            if (debtCollectHisBO.getCollectorStaffId() == null) {
                throw new SuzukiCommonException(ErrorCodeEnum.COLLECTOR_STAFF_ID_ISNULL);
            }
            DebtCollectHisDO debtCollectHisDO = BeanCopierUtil.convert(debtCollectHisBO, DebtCollectHisDO.class);
            //外勤具体催收人id是从前台记录的，所以后台只记录新增这条记录的员工id
            debtCollectHisDO.setStaffId(staffId);
            try {
                debtCollectHisManager.insertSelective(debtCollectHisDO);
            } catch (Exception e) {
                log.error("新增上门催收记录失败,debtCollectHisBO="+JSON.toJSONString(debtCollectHisBO), e);
                throw new SuzukiCommonException(ErrorCodeEnum.INSERT_VISIT_DEBT_COLLECT_HIS_FAIL);
            }
            try {
                //更新外勤的待办任务状态，所有该订单的上门催收待办设置为已处理
                OverdueCollectTaskQuery overdueCollectTaskQuery = new OverdueCollectTaskQuery();
                overdueCollectTaskQuery.createCriteria().andCustomerIdCardEqualTo(debtCollectHisDO.getCustomerIdCard())
                        .andOrderNoEqualTo(debtCollectHisDO.getOrderNo()).andStatusEqualTo(WaitingTaskEnum.STATUS_PENDING.getCode());
                for (OverdueCollectTaskDO overdueCollectTaskDO : overdueCollectTaskManager.selectByQuery(overdueCollectTaskQuery)) {
                    overdueCollectTaskDO.setStatus(WaitingTaskEnum.STATUS_PROCESSED.getCode());
                    overdueCollectTaskManager.updateByPrimaryKeySelective(overdueCollectTaskDO);
                }
            } catch (Exception e) {
                log.error("更新外勤待办任务失败,orderNo="+debtCollectHisDO.getOrderNo(), e);
                throw new SuzukiCommonException(ErrorCodeEnum.UPDATA_WAITING_TASK_PENDING_FAIL);
            }
            return true;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.VISIT_DEBT_COLLECT_HIS_ISNULL);
        }
    }

    /**
     * 新增拖车记录
     *
     * @param staffId
     * @param towingHisBO
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public Boolean addOrUpdateTowingHis(Long staffId, TowingHisBO towingHisBO) throws SuzukiCommonException {
        Optional<TowingHisBO> towingHisBOOptional = Optional.ofNullable(towingHisBO);
        if (towingHisBOOptional.isPresent()) {
            TowingHisDO towingHisDO = BeanCopierUtil.convert(towingHisBO, TowingHisDO.class);
            //外勤具体催收人id是从前台记录的，所以后台只记录新增这条记录的员工id
            towingHisDO.setStaffId(staffId);
            //补充车辆信息
            CarInfoQuery carInfoQuery = new CarInfoQuery();
            carInfoQuery.createCriteria().andOrderNoEqualTo(towingHisBO.getOrderNo());
            List<CarInfoDO> carInfoDOS = carInfoManager.selectByQuery(carInfoQuery);
            if (carInfoDOS != null && carInfoDOS.size() > 0) {
                CarInfoDO carInfoDO = carInfoDOS.get(0);
                towingHisDO.setVin(carInfoDO.getVinNo());
                towingHisDO.setEngineNo(carInfoDO.getEngineNum());
            }
            Optional<Long> towingIdOptional = Optional.ofNullable(towingHisDO.getTowingId());
            //id不为空表示更新该条记录
            if (towingIdOptional.isPresent()) {
                try {
                    towingHisManager.updateByPrimaryKeySelective(towingHisDO);
                } catch (Exception e) {
                    log.error("修改拖车记录失败,towingId="+towingHisDO.getTowingId(), e);
                    throw new SuzukiCommonException(ErrorCodeEnum.UPDATE_TOWING_HIS_FAIL);
                }
            } else {
                try {
                    towingHisManager.insertSelective(towingHisDO);
                } catch (Exception e) {
                    log.error("Exception", e);
                    throw new SuzukiCommonException(ErrorCodeEnum.INSERT_TOWING_HIS_FAIL);
                }
            }
            return true;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.TOWING_HIS__ISNULL);
        }
    }

    /**
     * 新增法院诉讼记录
     *
     * @param staffId
     * @param lawsuitHisBO
     * @return
     * @throws SuzukiCommonException
     */
    @Transactional
    @Override
    public Boolean addLawsuitHis(Long staffId, LawsuitHisBO lawsuitHisBO) throws SuzukiCommonException {
        Optional<LawsuitHisBO> lawsuitHisBOOptional = Optional.ofNullable(lawsuitHisBO);
        if (lawsuitHisBOOptional.isPresent()) {
            LawsuitHisDO lawsuitHisDO = BeanCopierUtil.convert(lawsuitHisBO, LawsuitHisDO.class);
            lawsuitHisDO.setStaffId(staffId);
            try {
                lawsuitHisManager.insertSelective(lawsuitHisDO);
            } catch (Exception e) {
                log.error("新增法院诉讼记录失败", e);
                throw new SuzukiCommonException(ErrorCodeEnum.INSERT_LAWSUIT_HIS_FAIL);
            }
            return true;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.LAWSUIT_HIS_ISNULL);
        }
    }

    /**
     * 从表格迭代器中获取数据
     *
     * @param rowIterator
     * @return
     */
    public List<OverdueListBO> iterateRow(Iterator<Row> rowIterator) throws SuzukiCommonException {
        Row row;
        Cell cell;
        Optional<Iterator> rowIterOptional = Optional.ofNullable(rowIterator);
        if (rowIterOptional.isPresent()) {
            //从第二行开始读取数据
            rowIterator.next();
            List<OverdueListBO> overdueListBOS = new ArrayList<>();
            while (rowIterator.hasNext()) {
                row = rowIterator.next();
                //跳过空行
                if (row == null) {
                    continue;
                }
                //获取此行单元格迭代器
                Iterator<Cell> cellIterator = row.cellIterator();
                OverdueListBO overdueRow = new OverdueListBO();
                //第一个单元格是客户姓名
                cell = cellIterator.next();
                if ("".equals(cell.toString())) {
                    //只要有空的单元格，跳过此行
                    continue;
                }
                overdueRow.setCustomerName(cell.getStringCellValue());
                //第二个单元格是银行卡号
                cell = cellIterator.next();
                if ("".equals(cell.toString())) {
                    //只要有空的单元格，跳过此行
                    continue;
                }
                overdueRow.setBankCardNo(cell.getStringCellValue());
                //第三个单元格是逾期金额
                cell = cellIterator.next();
                if ("".equals(cell.toString())) {
                    //只要有空的单元格，跳过此行
                    continue;
                }
                overdueRow.setAmount(new BigDecimal(cell.toString()));
                overdueListBOS.add(overdueRow);
            }
            return overdueListBOS;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.FILE_ISNULL);
        }
    }

    /**
     * 保存逾期清单到数据库
     *
     * @param overdueListBOS
     * @return
     */
    public Boolean saveOverdueList(Long staffId, List<OverdueListBO> overdueListBOS) throws SuzukiCommonException {
        //根据银行卡号找到订单，可能有多条，但只需要一个订单号就能拿到客户信息
        PostBankCardQuery postBankCardQuery = new PostBankCardQuery();
        postBankCardQuery.createCriteria().andRepayAccountEqualTo(overdueListBOS.get(0).getBankCardNo()).andIsDeletedEqualTo(IsDeletedEnum.NORMAL.getCode());
        List<PostBankCardDO> postBankCardDOS = postBankCardManager.selectByQuery(postBankCardQuery);
        if (CollectionUtils.isNotEmpty(postBankCardDOS)) {
            //根据订单号找到贷款信息，根据贷款信息找到银行编号，从数据字典中查出银行名称与银行编号
            LoanInfoDO loanInfoDO = loanInfoManager.selectByOrderNo(postBankCardDOS.get(0).getOrderNo());
            try {
                //删除数据库中的旧数据(删除条件：指定的银行的旧数据)，逻辑删除
                OverdueListQuery overdueListQuery = new OverdueListQuery();
                overdueListQuery.createCriteria().andBankIdEqualTo(loanInfoDO.getBankId());
                for (OverdueListDO overdueListDO : overdueListManager.selectByQuery(overdueListQuery)) {
                    overdueListDO.setStatus(RepayStatusEnum.DELETED.getCode());
                    overdueListManager.updateByPrimaryKeySelective(overdueListDO);
                }
            } catch (Exception e) {
                throw new SuzukiCommonException(ErrorCodeEnum.DELETE_OVERDUE_FAIL);
            }
            for (OverdueListBO overdueListBO : overdueListBOS) {
                DataDictDO dataDictDO = dataDictManager.selectByPrimaryKey(loanInfoDO.getBankId());
                overdueListBO.setBankId(loanInfoDO.getBankId());
                overdueListBO.setBankName(dataDictDO.getName());
                //应还款日为寄卡信息中的银行还款日，加上月份代表本期应还款，以后做数据是否重复的校验
                overdueListBO.setRepaymentDate(LocalDateTime.now().getYear() + "" + LocalDateTime.now().getMonthValue() + postBankCardDOS.get(0).getRepayDay());
                //根据订单号找到订单详情，再获取客户身份证号
                OrderDO orderDO = orderManager.selectByOrderNo(postBankCardDOS.get(0).getOrderNo());
                overdueListBO.setCustomerIdCard(orderDO.getCustomerIdCard());
                //设置逾期状态为未还款
                overdueListBO.setStatus(RepayStatusEnum.NOTPAID.getCode());
                //增加这条记录的员工编号
                overdueListBO.setStaffId(staffId);
                OverdueListDO overdueListDO = BeanCopierUtil.convert(overdueListBO, OverdueListDO.class);
                try {
                    //TODO:数据量较大时插入较慢，使用分批插入替代
                    overdueListManager.insertSelective(overdueListDO);
                } catch (Exception e) {
                    log.error("保存逾期清单失败", e);
                    throw new SuzukiCommonException(ErrorCodeEnum.INSERT_OVERDUE_FAIL);
                }
            }
        }else{
            throw new SuzukiCommonException(ErrorCodeEnum.POSTBANKCARD_NOT_FOUND);
        }
        return true;
    }

    /**
     * 分配外勤（上门催收）
     *
     * @param staffId
     * @param distributeCollectBO
     * @return
     * @throws SuzukiCommonException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean distributeCollectTask(Long staffId, DistributeCollectBO distributeCollectBO) throws SuzukiCommonException {
        Optional<DistributeCollectBO> distributeCollectBOOptional = Optional.ofNullable(distributeCollectBO);
        if (distributeCollectBOOptional.isPresent()) {
            try {
                //获取已存在的未处理的待办任务
                OverdueCollectTaskQuery overdueCollectTaskQuery = new OverdueCollectTaskQuery();
                overdueCollectTaskQuery.createCriteria().andOrderNoEqualTo(distributeCollectBO.getOrderNo()).andStatusEqualTo(WaitingTaskEnum.STATUS_PENDING.getCode());
                List<OverdueCollectTaskDO> overdueCollectTaskDOList = overdueCollectTaskManager.selectByQuery(overdueCollectTaskQuery);
                //生成新的待办任务
                OverdueCollectTaskDO overdueCollectTaskDO = new OverdueCollectTaskDO();
                overdueCollectTaskDO.setOrderNo(distributeCollectBO.getOrderNo());
                overdueCollectTaskDO.setCustomerName(distributeCollectBO.getCustomerName());
                overdueCollectTaskDO.setCustomerIdCard(distributeCollectBO.getCustomerIdCard());
                overdueCollectTaskDO.setStatus(WaitingTaskEnum.STATUS_PENDING.getCode());
                //设置催收任务表的任务创建者（分配人），即当前登录的用户
                overdueCollectTaskDO.setStaffId(staffId);
                for (StaffDTO staffDTO : staffRoleService.getStaffByDeptId(distributeCollectBO.getDeptId())) {
                    //对于已有该任务的员工，更新该记录而不是插入新记录
                    Boolean isStaffAlreadyExist = false;
                    for (OverdueCollectTaskDO aeOverdueCollectTaskDO : overdueCollectTaskDOList) {
                        if (aeOverdueCollectTaskDO.getHandlerId().equals(staffDTO.getStaffId())) {
                            isStaffAlreadyExist = true;
                            BeanCopierUtil.copy(aeOverdueCollectTaskDO, overdueCollectTaskDO);
                            //设置新的任务创建者（分配人），即当前登录的用户
                            overdueCollectTaskDO.setStaffId(staffId);
                        }
                    }
                    if (isStaffAlreadyExist) {
                        overdueCollectTaskManager.updateByPrimaryKeySelective(overdueCollectTaskDO);
                    } else {
                        //设置待办任务表的待办人（执行人）id，即对应分组下的员工id
                        overdueCollectTaskDO.setHandlerId(staffDTO.getStaffId());
                        try {
                            overdueCollectTaskManager.insertSelective(overdueCollectTaskDO);
                        } catch (Exception e) {
                            throw new SuzukiCommonException(ErrorCodeEnum.INSERT_OVERDUE_COLLECT_TASK_FAIL);
                        }
                    }
                    //插入后会生成主键，清除这个主键再插入下一个外勤组员工的待办
                    overdueCollectTaskDO.setTaskId(null);
                }
                return true;
            } catch (Exception e) {
                log.error("Exception", e);
                throw new SuzukiCommonException(ErrorCodeEnum.DISTRIBUTE_COLLECT_TASK_FAIL);
            }
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.DISTRIBUTE_COLLECT_ISNULL);
        }
    }

    /**
     * 从数据字典中获取部门列表
     *
     * @return
     * @throws SuzukiCommonException
     */
    @Override
    public List<DepartmentVO> getDepartmentListInDataDict(DataDictQuery dataDictQuery) throws SuzukiCommonException {
        List<DepartmentVO> departmentVOList = new ArrayList<>();
        for (DataDictDO dataDictDO : dataDictManager.selectByQuery(dataDictQuery)) {
            DepartmentVO departmentVO = new DepartmentVO();
            departmentVO.setDeptId(Long.parseLong(dataDictDO.getCode()));
            departmentVO.setDeptName(dataDictDO.getName());
            departmentVOList.add(departmentVO);
        }
        return departmentVOList;
    }

    /**
     * 获取订单对应的上门催收处理人（上门外勤）
     *
     * @param orderNo
     * @return
     */
    @Override
    public List<StaffDTO> getOrderCollectOutWorkers(String orderNo) {
        Optional<String> orderNoOptional = Optional.ofNullable(orderNo);
        if (orderNoOptional.isPresent()) {
            List<StaffDTO> staffDTOList = new ArrayList<>();
            OverdueCollectTaskQuery overdueCollectTaskQuery = new OverdueCollectTaskQuery();
            overdueCollectTaskQuery.createCriteria().andOrderNoEqualTo(orderNo).andStatusEqualTo(WaitingTaskEnum.STATUS_PENDING.getCode());
            for (OverdueCollectTaskDO overdueCollectTaskDO : overdueCollectTaskManager.selectByQuery(overdueCollectTaskQuery)) {
                StaffDTO staffDTO = staffRoleService.selectByStaffName(overdueCollectTaskDO.getHandlerId());
                staffDTOList.add(staffDTO);
            }
            return staffDTOList;
        } else {
            throw new SuzukiCommonException(ErrorCodeEnum.ORDER_NO_ISNULL);
        }
    }

}
